// Copyright 叶湘 ( weixin:yexiang841, email:yexiang841@qq.com ), Shitouren Studio. All Rights Reserved.

#include "Hit/Q3D_CPPU_Hit.h"
#include "Hit/Q3D_CPPI_HitTarget.h"
#include "Hit/Q3D_CPPU_HitType.h"
#include "Hit/Q3D_CPPU_HitMode.h"
#include "Hit/Q3D_CPPU_HitValue.h"
#include "Property/Q3D_CPPE_PropertyName.h"
#include "Property/Q3D_CPPI_PropertyState.h"
#include "Property/Q3D_CPPU_PropertyPLIPro.h"

void UQ3D_CPPU_Hit::Q3D_F_Hit_Set(
    EQ3D_CPPE_HitType enum_hit_type,
    EQ3D_CPPE_HitMode enum_hit_mode,
    int int_hit_count,
    float float_hit_interval,
    float float_halo_time,
    EQ3D_CPPE_HitValue enum_hit_value,
    int int_value_int,
    float float_percent_by_max,
    float float_percent_by_now,
    AActor *ptr_a_hit_maker,
    AActor *ptr_a_hit_causer,
    UQ3D_CPPU_Hit *&ptr_u_hit)
{
    switch (enum_hit_type)
    {
    case EQ3D_CPPE_HitType::Damage:
        this->Q3D_F_HitType_SetDamage(ptr_u_hit);
        break;
    case EQ3D_CPPE_HitType::Recover:
        this->Q3D_F_HitType_SetRecover(ptr_u_hit);
        break;
    default:
        break;
    }
    switch (enum_hit_mode)
    {
    case EQ3D_CPPE_HitMode::Hit_Once:
        this->Q3D_F_HitMode_SetHitOnce(ptr_u_hit);
        break;
    case EQ3D_CPPE_HitMode::Hit_Multiple:
        this->Q3D_F_HitMode_SetHitMultiple(int_hit_count, float_hit_interval, ptr_u_hit);
        break;
    case EQ3D_CPPE_HitMode::Hit_Infinite:
        this->Q3D_F_HitMode_SetHitInfinite(float_hit_interval, ptr_u_hit);
        break;
    case EQ3D_CPPE_HitMode::Halo_Const:
        this->Q3D_F_HitMode_SetHaloConst(ptr_u_hit);
        break;
    case EQ3D_CPPE_HitMode::Halo_Timed:
        this->Q3D_F_HitMode_SetHaloTimed(float_halo_time, ptr_u_hit);
        break;
    default:
        break;
    }
    switch (enum_hit_value)
    {
    case EQ3D_CPPE_HitValue::Value_Int:
        this->Q3D_F_HitValue_SetInt(int_value_int, ptr_u_hit);
        break;
    case EQ3D_CPPE_HitValue::Value_PercentByMax:
        this->Q3D_F_HitValue_SetPercentByMax(float_percent_by_max, ptr_u_hit);
        break;
    case EQ3D_CPPE_HitValue::Value_PercentByNow:
        this->Q3D_F_HitValue_SetPercentByNow(float_percent_by_now, ptr_u_hit);
        break;
    default:
        break;
    }
    this->Q3D_F_HitMaker_Set(ptr_a_hit_maker, ptr_u_hit);
    this->Q3D_F_HitCauser_Set(ptr_a_hit_causer, ptr_u_hit);
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_Hit_SetToTarget(
    EQ3D_CPPE_HitType enum_hit_type,
    EQ3D_CPPE_HitMode enum_hit_mode,
    int int_hit_count,
    float float_hit_interval,
    float float_halo_time,
    EQ3D_CPPE_HitValue enum_hit_value,
    int int_value_int,
    float float_percent_by_max,
    float float_percent_by_now,
    AActor *ptr_a_hit_maker,
    AActor *ptr_a_hit_causer,
    AActor *ptr_a_hit_target,
    UQ3D_CPPU_Hit *&ptr_u_hit,
    bool &bool_success,
    FString &string_log)
{
    this->Q3D_F_Hit_Set(
        enum_hit_type,
        enum_hit_mode,
        int_hit_count,
        float_hit_interval,
        float_halo_time,
        enum_hit_value,
        int_value_int,
        float_percent_by_max,
        float_percent_by_now,
        ptr_a_hit_maker,
        ptr_a_hit_causer,
        ptr_u_hit);
    this->Q3D_F_SetToTarget(ptr_a_hit_target, bool_success, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_SetToTarget(AActor *ptr_a_hit_target, bool &bool_success, FString &string_log)
{
    UQ3D_CPPU_Hit *ptr_u_hit_tmp;
    // HitType 检测
    if (!this->Ptr_U_HitType)
    {
        this->Q3D_F_HitType_SetDamage(ptr_u_hit_tmp);
    }
    // HitMode 检测
    if (!this->Ptr_U_HitMode)
    {
        this->Q3D_F_HitMode_SetHitOnce(ptr_u_hit_tmp);
    }
    // HitValue 检测
    if (!this->Ptr_U_HitValue)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitValue";
        return;
    }
    // HitTarget 检测
    if (!ptr_a_hit_target)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_A_HitTarget";
        return;
    }
    // HitTarget 必须实现 HitTarget 接口
    IQ3D_CPPI_HitTarget *ptr_i_hit_target = Cast<IQ3D_CPPI_HitTarget>(ptr_a_hit_target);
    if (!ptr_i_hit_target)
    {
        bool_success = false;
        string_log = "Cast_To_Q3D_CPPI_HitTarget_Failed";
        return;
    }
    // 保存 HitTarget
    this->Ptr_A_HitTarget = ptr_a_hit_target;
    // 通过接口发送命中
    ptr_i_hit_target->Execute_Q3D_IF_Hit_Set(ptr_a_hit_target, this, bool_success, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitType_SetDamage(UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitTypeDamage 类型
    UQ3D_CPPU_HitTypeDamage *ptr_u_hit_type_damage = NewObject<UQ3D_CPPU_HitTypeDamage>(this->GetOuter());
    ptr_u_hit_type_damage->Enum_HitDamageStyle = EQ3D_CPPE_HitDamageStyle::DS_Normal;
    // 设置 HitType
    this->Ptr_U_HitType = ptr_u_hit_type_damage;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitDamageStyle_Set(EQ3D_CPPE_HitDamageStyle enum_hit_damage_style, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    if (!this->Ptr_U_HitType)
    {
        ptr_u_hit = this;
        return;
    }
    UQ3D_CPPU_HitTypeDamage *ptr_u_hit_type_damage_tmp = Cast<UQ3D_CPPU_HitTypeDamage>(this->Ptr_U_HitType);
    if (!ptr_u_hit_type_damage_tmp)
    {
        ptr_u_hit = this;
        return;
    }
    // 写入 Q3D_CPPE_HitDamageStyle 类型
    ptr_u_hit_type_damage_tmp->Enum_HitDamageStyle = enum_hit_damage_style;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitType_SetRecover(UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitTypeRecover 类型
    UQ3D_CPPU_HitTypeRecover *ptr_u_hit_type_recover = NewObject<UQ3D_CPPU_HitTypeRecover>(this->GetOuter());
    // 设置 HitType
    this->Ptr_U_HitType = ptr_u_hit_type_recover;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitType_GetEnum(EQ3D_CPPE_HitType &enum_hit_type) const
{
    enum_hit_type = this->Q3D_F_HitType_GetEnum();
    return;
}

EQ3D_CPPE_HitType UQ3D_CPPU_Hit::Q3D_F_HitType_GetEnum() const
{
    EQ3D_CPPE_HitType enum_hit_type;
    this->Ptr_U_HitType->Q3D_F_HitType_GetEnum(enum_hit_type);
    return enum_hit_type;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_SetHitOnce(UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitModeHitOnce 类型
    UQ3D_CPPU_HitModeHitOnce *ptr_u_hit_mode_hit_once = NewObject<UQ3D_CPPU_HitModeHitOnce>(this->GetOuter());
    ptr_u_hit_mode_hit_once->Ptr_U_Hit = this;
    // 设置 HitMode
    Ptr_U_HitMode = ptr_u_hit_mode_hit_once;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_SetHitMultiple(int int_hit_count, float float_hit_interval, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitModeHitMultiple 类型
    UQ3D_CPPU_HitModeHitMultiple *ptr_u_hit_mode_hit_multiple = NewObject<UQ3D_CPPU_HitModeHitMultiple>(this->GetOuter());
    // 设置计数器
    ptr_u_hit_mode_hit_multiple->Int_HitCount = (int_hit_count >= 0 ? int_hit_count : 0);
    ptr_u_hit_mode_hit_multiple->Float_HitInterval = (float_hit_interval > 0 ? float_hit_interval : 1.0f);
    ptr_u_hit_mode_hit_multiple->Ptr_U_Hit = this;
    // 设置触发间隔
    // 设置 HitMode
    this->Ptr_U_HitMode = ptr_u_hit_mode_hit_multiple;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_SetHitInfinite(float float_hit_interval, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitModeHitInfinite 类型
    UQ3D_CPPU_HitModeHitInfinite *ptr_u_hit_mode_hit_infinite = NewObject<UQ3D_CPPU_HitModeHitInfinite>(this->GetOuter());
    // 触发间隔
    ptr_u_hit_mode_hit_infinite->Float_HitInterval = (float_hit_interval > 0 ? float_hit_interval : 1.0f);
    ptr_u_hit_mode_hit_infinite->Ptr_U_Hit = this;
    // 设置 HitMode
    this->Ptr_U_HitMode = ptr_u_hit_mode_hit_infinite;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_SetHaloConst(UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitModeHaloConst 类型
    UQ3D_CPPU_HitModeHaloConst *ptr_u_hit_mode_halo_const = NewObject<UQ3D_CPPU_HitModeHaloConst>(this->GetOuter());
    ptr_u_hit_mode_halo_const->Ptr_U_Hit = this;
    // 设置 HitMode
    this->Ptr_U_HitMode = ptr_u_hit_mode_halo_const;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_SetHaloTimed(float float_halo_time, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitModeHaloTimed类型
    UQ3D_CPPU_HitModeHaloTimed *ptr_u_hit_mode_halo_timed = NewObject<UQ3D_CPPU_HitModeHaloTimed>(this->GetOuter());
    ptr_u_hit_mode_halo_timed->Float_HaloTime = float_halo_time;
    ptr_u_hit_mode_halo_timed->Ptr_U_Hit = this;
    // 设置 HitMode
    this->Ptr_U_HitMode = ptr_u_hit_mode_halo_timed;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMode_GetEnum(EQ3D_CPPE_HitMode &enum_hit_mode) const
{
    enum_hit_mode = this->Q3D_F_HitMode_GetEnum();
    return;
}

EQ3D_CPPE_HitMode UQ3D_CPPU_Hit::Q3D_F_HitMode_GetEnum() const
{
    EQ3D_CPPE_HitMode enum_hit_mode;
    this->Ptr_U_HitMode->Q3D_F_HitMode_GetEnum(enum_hit_mode);
    return enum_hit_mode;
}

void UQ3D_CPPU_Hit::Q3D_F_HitValue_SetInt(int32 int_value_int, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitValueInt 类型
    UQ3D_CPPU_HitValueInt *ptr_u_hit_value_int = NewObject<UQ3D_CPPU_HitValueInt>(this->GetOuter());
    ptr_u_hit_value_int->Int_Value_Int = (int_value_int >= 0 ? int_value_int : 0);
    ptr_u_hit_value_int->Ptr_U_Hit = this;
    // 设置 HitValue
    this->Ptr_U_HitValue = ptr_u_hit_value_int;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitValue_SetPercentByMax(float float_percent_by_max, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitValueInt 类型
    UQ3D_CPPU_HitValuePercentByMax *ptr_u_hit_value_percent_by_max = NewObject<UQ3D_CPPU_HitValuePercentByMax>(this->GetOuter());
    ptr_u_hit_value_percent_by_max->Float_PercentByMax = (float_percent_by_max >= 0.f ? float_percent_by_max : 0.f);
    ptr_u_hit_value_percent_by_max->Ptr_U_Hit = this;
    // 设置 HitValue
    this->Ptr_U_HitValue = ptr_u_hit_value_percent_by_max;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitValue_SetPercentByNow(float float_percent_by_now, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 新建 HitValueInt 类型
    UQ3D_CPPU_HitValuePercentByNow *ptr_u_hit_value_percent_by_now = NewObject<UQ3D_CPPU_HitValuePercentByNow>(this->GetOuter());
    ptr_u_hit_value_percent_by_now->Float_PercentByNow = (float_percent_by_now >= 0.f ? float_percent_by_now : 0.f);
    ptr_u_hit_value_percent_by_now->Ptr_U_Hit = this;
    // 设置 HitValue
    this->Ptr_U_HitValue = ptr_u_hit_value_percent_by_now;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitValue_GetEnum(EQ3D_CPPE_HitValue &enum_hit_value) const
{
    enum_hit_value = this->Q3D_F_HitValue_GetEnum();
    return;
}

EQ3D_CPPE_HitValue UQ3D_CPPU_Hit::Q3D_F_HitValue_GetEnum() const
{
    EQ3D_CPPE_HitValue enum_hitvalue;
    this->Ptr_U_HitValue->Q3D_F_HitValue_GetEnum(enum_hitvalue);
    return enum_hitvalue;
}

void UQ3D_CPPU_Hit::Q3D_F_HitValue_Get(int32 &int_hit_value) const
{
    int_hit_value = this->Q3D_F_HitValue_Get();
    return;
}

int32 UQ3D_CPPU_Hit::Q3D_F_HitValue_Get() const
{
    int32 int_hit_value_tmp;
    this->Ptr_U_HitValue->Q3D_F_HitValue_Get(int_hit_value_tmp);
    return int_hit_value_tmp;
}

void UQ3D_CPPU_Hit::Q3D_F_HitMaker_Set(AActor *ptr_a_hit_maker, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 保存 HitMaker
    this->Ptr_A_HitMaker = ptr_a_hit_maker;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_HitCauser_Set(AActor *ptr_a_hit_causer, UQ3D_CPPU_Hit *&ptr_u_hit)
{
    // 保存 HitCauser
    this->Ptr_A_HitCauser = ptr_a_hit_causer;
    ptr_u_hit = this;
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_PropertyPLIPro_Get(UQ3D_CPPU_PropertyPLIPro *&ptr_u_property_pli_pro, FString &string_log) const
{
    // HitTarget 检测
    if (!this->Ptr_A_HitTarget)
    {
        ptr_u_property_pli_pro = nullptr;
        string_log = "Invalid_Ptr_A_HitTarget";
        return;
    }
    // HitTarget 必须实现 PropertyState 接口
    IQ3D_CPPI_PropertyState *ptr_i_property_state = Cast<IQ3D_CPPI_PropertyState>(this->Ptr_A_HitTarget);
    if (!ptr_i_property_state)
    {
        ptr_u_property_pli_pro = nullptr;
        string_log = "Cast_To_Q3D_CPPI_PropertyState_Failed";
        return;
    }
    // 读取 PropertyState
    UQ3D_CPPU_PropertyState *ptr_u_property_state;
    ptr_i_property_state->Execute_Q3D_IF_PropertyState_Get(this->Ptr_A_HitTarget, ptr_u_property_state);
    if (!ptr_u_property_state)
    {
        ptr_u_property_pli_pro = nullptr;
        string_log = "Invalid_Ptr_U_PropertyState";
        return;
    }
    ptr_u_property_state->Q3D_F_PropertyPLIPro_Get(this->Enum_PropertyName, ptr_u_property_pli_pro, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_Hit_Execute_ByHitTarget(bool &bool_success, FString &string_log)
{
    // HitType 检测
    if (!this->Ptr_U_HitType)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitType";
        return;
    }
    // HitMode 检测
    if (!this->Ptr_U_HitMode)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitMode";
        return;
    }
    // HitValue 检测
    if (!this->Ptr_U_HitValue)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitValue";
        return;
    }
    // HitTarget 检测
    if (!this->Ptr_A_HitTarget)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_A_HitTarget";
        return;
    }
    // 读取 Property
    UQ3D_CPPU_PropertyPLIPro *ptr_u_property_pli_pro;
    this->Q3D_F_PropertyPLIPro_Get(ptr_u_property_pli_pro, string_log);
    if (!ptr_u_property_pli_pro)
    {
        bool_success = false;
        return;
    }

    /* 
     * 建议在此在此进行相性计算，存储到 HitValue
     */

    // 由 HitMode 执行命中，直接重写 bool_success 和 string_log
    this->Ptr_U_HitMode->Q3D_F_Hit_Execute(ptr_u_property_pli_pro, bool_success, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_Hit_Execute_OnProperty(UQ3D_CPPU_PropertyPLIPro *ptr_u_property_pli_pro, bool &bool_success, FString &string_log)
{
    // HitType 检测
    if (!this->Ptr_U_HitType)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitType";
        return;
    }
    // HitMode 检测
    if (!this->Ptr_U_HitMode)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitMode";
        return;
    }
    // HitValue 检测
    if (!this->Ptr_U_HitValue)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitValue";
        return;
    }
    // HitTarget 检测
    if (!this->Ptr_A_HitTarget)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_A_HitTarget";
        return;
    }
    // PropertyPLIPro 检测
    if (!ptr_u_property_pli_pro)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_PropertyPLIPro";
        return;
    }
    if (ptr_u_property_pli_pro->Enum_PropertyName != this->Enum_PropertyName)
    {
        bool_success = false;
        string_log = "PropertyNameIn[" + StaticEnum<EQ3D_CPPE_PropertyName>()->GetNameStringByValue((uint8)(ptr_u_property_pli_pro->Enum_PropertyName)) + "]_!=_PropertyNameHit[" + StaticEnum<EQ3D_CPPE_PropertyName>()->GetNameStringByValue((uint8)(this->Enum_PropertyName)) + "]";
        return;
    }

    /* 
     * 建议在此在此进行相性计算，存储到 HitValue
     */

    // 由 HitMode 执行命中
    this->Ptr_U_HitMode->Q3D_F_Hit_Execute(ptr_u_property_pli_pro, bool_success, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_Hit_Cancel(bool &bool_success, FString &string_log)
{
    // HitType 检测
    if (!this->Ptr_U_HitType)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitType";
        return;
    }
    // HitMode 检测
    if (!this->Ptr_U_HitMode)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitMode";
        return;
    }
    // HitValue 检测
    if (!this->Ptr_U_HitValue)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_U_HitValue";
        return;
    }
    // HitTarget 检测
    if (!this->Ptr_A_HitTarget)
    {
        bool_success = false;
        string_log = "Invalid_Ptr_A_HitTarget";
        return;
    }
    // 由 HitMode 执行命中
    this->Ptr_U_HitMode->Q3D_F_Hit_Cancel(bool_success, string_log);
    return;
}

void UQ3D_CPPU_Hit::Q3D_F_ToString(FString &string_info) const
{
    string_info = this->Q3D_F_ToString();
    return;
}

FString UQ3D_CPPU_Hit::Q3D_F_ToString() const
{
    EQ3D_CPPE_HitMode enum_hit_mode_tmp;
    this->Ptr_U_HitMode->Q3D_F_HitMode_GetEnum(enum_hit_mode_tmp);
    EQ3D_CPPE_HitType enum_hit_type_tmp;
    this->Ptr_U_HitType->Q3D_F_HitType_GetEnum(enum_hit_type_tmp);
    return (this->Ptr_U_HitMode ? StaticEnum<EQ3D_CPPE_HitMode>()->GetNameStringByValue((uint8)(enum_hit_mode_tmp)) : "Unknown") + "(" + (this->Ptr_U_HitType ? StaticEnum<EQ3D_CPPE_HitType>()->GetNameStringByValue((uint8)(enum_hit_type_tmp)) : "Unknown") + ")_On_[" + StaticEnum<EQ3D_CPPE_PropertyName>()->GetNameStringByValue((uint8)(this->Enum_PropertyName)) + "]";
}

UWorld *UQ3D_CPPU_Hit::GetWorld() const
{
    UObject *ptr_u_outer = this->GetOuter();
    if (ptr_u_outer && ptr_u_outer->GetClass()->IsChildOf(AActor::StaticClass()))
    {
        return Cast<AActor>(ptr_u_outer)->GetWorld();
    }
    if (this->Ptr_A_HitMaker)
    {
        return this->Ptr_A_HitMaker->GetWorld();
    }
    if (this->Ptr_A_HitCauser)
    {
        return this->Ptr_A_HitCauser->GetWorld();
    }
    if (this->Ptr_A_HitTarget)
    {
        return this->Ptr_A_HitTarget->GetWorld();
    }
    return nullptr;
}
